﻿using System;
using System.Collections.Generic;
using ParserGenerator.Collections;

namespace ParserGenerator.ScannerConstruction
{
    [Serializable]
    public sealed class ScannerAutomatonStateGroup : ReadOnlyLinkedList<ScannerAutomatonState>
    {
        public int Number => Representative.Number;
        public ScannerAutomatonState Representative => Items.First.Value;

        internal ScannerAutomatonStateGroup()
            : base(new LinkedList<ScannerAutomatonState>())
        {
        }

        internal ScannerAutomatonStateGroup(ScannerAutomatonStateTable states)
            : base(new LinkedList<ScannerAutomatonState>(states))
        {
            foreach (ScannerAutomatonState state in Items)
                state.Group = this;
        }

        internal void Split(List<ScannerAutomatonStateGroup> groups)
        {
            if (groups == null)
                throw new ArgumentNullException(nameof(groups));
            if (Items.Count > 1)
            {
                ScannerAutomatonState x = Items.First.Value;
                ScannerAutomatonStateGroup group = null;
                LinkedListNode<ScannerAutomatonState> p = Items.First.Next;
                while (p != null)
                {
                    ScannerAutomatonState y = p.Value;
                    if (y.CanMergeWith(x))
                        p = p.Next;
                    else
                    {
                        if (group == null)
                        {
                            group = new ScannerAutomatonStateGroup();
                            groups.Add(group);
                        }
                        LinkedListNode<ScannerAutomatonState> next = p.Next;
                        Items.Remove(p);
                        group.Items.AddLast(p);
                        y.Group = group;
                        p = next;
                    }
                }
            }
        }

        public sealed override string ToString()
        {
            return "[" + string.Join(", ", Items) + "]";
        }
    }
}
